package cn.micro.system.manage.controller;



import cn.micro.system.manage.annotate.OldPasswordIsTrue;
import cn.micro.system.manage.annotate.UniqueUser;
import cn.micro.system.manage.common.log.annotation.Log;
import cn.micro.system.manage.common.log.enums.BusinessType;
import cn.micro.system.manage.common.result.Result;
import cn.micro.system.manage.common.security.utils.SecurityUtil;
import cn.micro.system.manage.common.utils.JwtHelper;
import cn.micro.system.manage.common.utils.ResponseUtil;
import cn.micro.system.manage.common.vaildate.ValidateGroup;
import cn.micro.system.manage.entity.SysDimUser;
import cn.micro.system.manage.entity.SysDimUserRole;
import cn.micro.system.manage.entity.dto.UpdatePasswordDTO;
import cn.micro.system.manage.entity.dto.UpdateStatusDTO;
import cn.micro.system.manage.entity.vo.SysUserQueryVo;
import cn.micro.system.manage.service.SysDimUserRoleService;
import cn.micro.system.manage.service.SysDimUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author wr
 * @since 2023-12-25
 */
@RestController
@RequestMapping("/manage/sysDimUser")
@Validated
@RequiredArgsConstructor
public class SysDimUserController {

    private final SysDimUserService sysDimUserService;

    private final SysDimUserRoleService sysDimUserRoleService;

    private final JwtHelper jwtHelper;

    @ApiOperation("更改用户状态")
    @PutMapping("updateStatus")
    @Log(title = "用户管理--更改用户状态",businessType = BusinessType.UPDATE)
    @PreAuthorize("hasAuthority('bnt.sysUser.updateStatus')")
    public Result updateStatus(@Validated @RequestBody UpdateStatusDTO dto) {
        sysDimUserService.updateStatus(dto.getId(),dto.getStatus());
        return Result.success();
    }

    @ApiOperation("用户列表")
    @GetMapping("/{page}/{size}")
    @PreAuthorize("hasAuthority('bnt.sysUser.list')")
    public Result list(@PathVariable int page,
                       @PathVariable int size,
                       SysUserQueryVo sysUserQueryVo) {
        return Result.success(new PageInfo<>(sysDimUserService.selectPage(page,size,sysUserQueryVo)));
    }

    @ApiOperation("添加用户")
    @PostMapping("save")
    @Log(title = "用户管理--添加用户",businessType = BusinessType.INSERT)
    @PreAuthorize("hasAuthority('bnt.sysUser.add')")
    @Transactional
    public Result save(@Validated(value = ValidateGroup.add.class) @UniqueUser @RequestBody SysDimUser user) {
        user.setPassword(SecurityUtil.encryptPassword(user.getPassword()));
        boolean is_Success = sysDimUserService.save(user);
        if(is_Success) {
            if (user.getRoleIds()!=null && user.getRoleIds().size() > 0){
                List<SysDimUserRole> userRoleList = new ArrayList<>();
                for (int i = 0; i < user.getRoleIds().size(); i++) {
                    SysDimUserRole sysDimUserRole = new SysDimUserRole();
                    sysDimUserRole.setUserId(Long.parseLong(user.getId()));
                    sysDimUserRole.setRoleId(Long.parseLong(user.getRoleIds().get(i)));
                    userRoleList.add(sysDimUserRole);
                }
                is_Success = sysDimUserRoleService.saveBatch(userRoleList);
            }
        }
        if(is_Success) {
            return Result.success();
        } else {
            return Result.fail();
        }
    }

    @ApiOperation("根据id查询")
    @GetMapping("getUser/{id}")
    @PreAuthorize("hasAuthority('bnt.sysUser.list')")
    public Result getUser(@PathVariable Long id) {
        return Result.success(sysDimUserService.getDetail(id));
    }

    @ApiOperation("修改用户")
    @PutMapping("edit")
    @PreAuthorize("hasAuthority('bnt.sysUser.update')")
    @Log(title = "用户管理--修改用户",businessType = BusinessType.UPDATE)
    public Result edit(@Validated(value = ValidateGroup.edit.class) @UniqueUser @RequestBody SysDimUser user) {
        boolean is_Success = sysDimUserService.updateById(user);
        if(is_Success) {
            return Result.success();
        } else {
            return Result.fail();
        }
    }

    @ApiOperation("删除用户")
    @DeleteMapping("remove/{id}")
    @PreAuthorize("hasAuthority('bnt.sysUser.remove')")
    @Log(title = "用户管理--删除用户",businessType = BusinessType.DELETE)
    public Result remove(@PathVariable String id) {
        boolean is_Success = sysDimUserService.removeById(id);
        if(is_Success) {
            return Result.success();
        } else {
            return Result.fail();
        }
    }


    @GetMapping("info")
    public Result info(HttpServletRequest request) {
        //获取请求头token字符串
        String token = ResponseUtil.resolveToken(request);
        //从token字符串获取用户名称（id）
        String username = jwtHelper.getUsername(token);
        //根据用户名称获取用户信息（基本信息 和 菜单权限 和 按钮权限数据）
        Map<String,Object> map = sysDimUserService.getUserInfo(username);
        return Result.success(map);
    }

    @PutMapping ("updatePassword")
    @PreAuthorize("hasAuthority('bnt.sysUser.updatePassword')")
    @Log(title = "用户管理--修改密码",businessType = BusinessType.UPDATE,isSaveRequestData = false)
    public Object updatePassword(@Validated(value = ValidateGroup.updatePassword.class) @OldPasswordIsTrue @RequestBody UpdatePasswordDTO dto){
        SysDimUser sysDimUser = new SysDimUser();
        sysDimUser.setId(dto.getId());
        sysDimUser.setPassword(SecurityUtil.encryptPassword(dto.getNewPassword()));
        if (!sysDimUserService.updateById(sysDimUser)){
            return Result.fail();
        }
        return Result.success();
    }

}
